package com.shxy.config;

import com.shxy.common.ApiResult;
import com.shxy.common.ResultCode;
import lombok.extern.java.Log;
import org.apache.commons.lang3.StringUtils;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.NoHandlerFoundException;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

/**
 * 统一异常处理
 */
@RestControllerAdvice
@Log
public class GlobalExceptionHandler {

    /**
     * 输入验证异常处理
     * @param exception
     * @return
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ApiResult validateExceptionHandler(MethodArgumentNotValidException exception) {
        BindingResult br = exception.getBindingResult();
        Map<String, Object> maps;

        if(br.hasErrors()) {
            List<FieldError> errors = br.getFieldErrors();
            maps = new HashMap<>(errors.size());
            errors.forEach(error -> {
                maps.put(error.getField(), error.getDefaultMessage());
            });
        }
        else {
            maps = Collections.EMPTY_MAP;
        }

        ArrayList<Object> errors = new ArrayList<>(maps.values());
        log.info(StringUtils.join(errors.toArray()));
        return ApiResult.fail(ResultCode.PARAM_NOT_VALID, StringUtils.join(errors.toArray(), ","));
    }

    /**
     * 参数缺失异常处理
     * @param exception
     * @return
     */
    @ExceptionHandler(MissingServletRequestParameterException.class)
    public ApiResult missingParameterExceptionHandler(MissingServletRequestParameterException exception){
        return ApiResult.fail(ResultCode.PARAM_NOT_COMPLETE);
    }

    /**
     * url路径异常
     * @param exception
     * @return
     */
    @ExceptionHandler(NoHandlerFoundException.class)
    public ApiResult noHandlerFoundExceptionHandler(NoHandlerFoundException exception) {
        return ApiResult.fail(ResultCode.URL_ERROR);
    }

    @ExceptionHandler(value = Exception.class)
    public ApiResult jsonErrorHandler(HttpServletRequest request, Exception exception) throws Exception {
        exception.printStackTrace();
        return ApiResult.fail();
    }
}
